home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / macabuse / imlib / jwindow.c < prev    next >
C/C++ Source or Header  |  1997-05-20  |  15KB  |  621 lines

  1. #include "video.hpp"
  2. #include "image.hpp"
  3. #include "event.hpp"
  4. #include "filter.hpp"
  5. #include "event.hpp"
  6. #include "jwindow.hpp"
  7.  
  8. int jw_left=5,jw_right=5,jw_top=15,jw_bottom=5;
  9.  
  10. int frame_top() { return jw_top; }
  11. int frame_bottom() { return jw_bottom; }
  12. int frame_left() { return jw_left; }
  13. int frame_right() { return jw_right; }
  14.  
  15. ifield::~ifield() { ; }
  16.  
  17. void set_frame_size(int x)
  18. {  
  19.   if (x<1) x=1;
  20.   jw_left=x;
  21.   jw_right=x;
  22.   jw_top=10+x;
  23.   jw_bottom=x;
  24. }
  25.  
  26. extern image *screen;
  27.  
  28.  // true if a window lies in this area
  29. int window_manager::window_in_area(int x1, int y1, int x2, int y2)
  30. {
  31.   for (jwindow *f=first;f;f=f->next) 
  32.     if (f->x<=x2 && f->y<=y2 && f->x+f->l-1>=x1 && f->y+f->h-1>=y1)
  33.       return 1;
  34.   return 0;
  35. }
  36.  
  37. void window_manager::grab_focus(jwindow *j)
  38. { grab=j; }
  39.  
  40. void window_manager::release_focus()
  41. { grab=NULL; }
  42.  
  43.  
  44. void window_manager::close_window(jwindow *j)
  45. {
  46.   jwindow *k;
  47.   if (grab==j) grab=NULL;
  48.   if (state==dragging && j==drag_window)  // close the window we were dragging
  49.     state=inputing;
  50.  
  51.   if (j==first)
  52.     first=first->next;
  53.   else
  54.   {
  55.     for (k=first;k->next!=j;k=k->next)
  56.       k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  57.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  58.     k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  59.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  60.     k->next=j->next;
  61.   }
  62.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  63.   delete j;
  64. }
  65.  
  66. void window_manager::hide_windows()
  67. {
  68.   jwindow *p;
  69.   for (p=first;p;p=p->next)
  70.   {
  71.     if (!p->property.hidden)
  72.     {
  73.       p->property.hidden=1;
  74.       screen->add_dirty(p->x,p->y,p->x+p->l-1,p->y+p->h-1);
  75.     }
  76.   }
  77. }
  78.  
  79. void window_manager::show_windows()
  80. {
  81.   jwindow *p;
  82.   for (p=first;p;p=p->next)
  83.     if (p->property.hidden)
  84.       show_window(p);      
  85. }
  86.  
  87. void window_manager::hide_window(jwindow *j)
  88. {
  89.   jwindow *k;
  90.   if (j==first)
  91.     first=first->next;
  92.   else
  93.   {
  94.     for (k=first;k->next!=j;k=k->next)
  95.       k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  96.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  97.     k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  98.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  99.     k->next=j->next;
  100.   }
  101.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  102.   j->property.hidden=1;
  103. }
  104.  
  105. void window_manager::show_window(jwindow *j)
  106. {
  107.   if (j->property.hidden)
  108.   {
  109.     j->property.hidden=0;
  110.     j->screen->add_dirty(0,0,j->l-1,j->h-1);
  111.   }
  112. }
  113.  
  114. void window_manager::get_event(event &ev)
  115. {
  116.   jwindow *j;
  117.   eh->get_event(ev);
  118.   if (ev.type==EV_KEY)
  119.     key_state[ev.key]=1;
  120.   else if (ev.type==EV_KEYRELEASE)
  121.     key_state[ev.key]=0;
  122.  
  123.   if (state==inputing)
  124.   {
  125.     for (ev.window=NULL,j=first;j;j=j->next)
  126.       if (!j->property.hidden && ev.mouse_move.x>=j->x && ev.mouse_move.y>=j->y &&
  127.           ev.mouse_move.x<j->x+j->l && ev.mouse_move.y<j->y+j->h)
  128.         ev.window=j;
  129.  
  130.     if (!ev.window && grab) ev.window=grab;
  131.  
  132.     if (ev.window)
  133.     {
  134.       int closew=0,movew=0;
  135.  
  136.       if ((ev.type==EV_MOUSE_BUTTON && ev.mouse_button==1 && ev.window &&
  137.        ev.mouse_move.x>=ev.window->x && ev.mouse_move.y>=ev.window->y &&
  138.        ev.mouse_move.x<ev.window->x+ev.window->l && ev.mouse_move.y<ev.window->y+ev.window->y1()))
  139.       {
  140.     if (ev.mouse_move.x-ev.window->x<11) closew=1;
  141.     else if (ev.window->property.moveable) movew=1;
  142.       } else if (grab)
  143.         ev.window=grab;
  144.  
  145.       if (ev.type==EV_KEY && ev.key==JK_ESC)
  146.         closew=1;
  147.  
  148.       
  149.     
  150.       if (closew)
  151.         ev.type=EV_CLOSE_WINDOW;
  152.       else if (movew)
  153.       {    
  154.     int red=0;
  155.     if (ev.window==first)       // see if we need to raise the window
  156.     {
  157.       first=first->next;
  158.       if (first)
  159.         red=1;
  160.     }
  161.     else
  162.     {
  163.       jwindow *last=first;
  164.       for (;last->next!=ev.window;last=last->next);
  165.       if (ev.window->next)
  166.         red=1;
  167.       last->next=ev.window->next;
  168.     }
  169.     if (!first)
  170.       first=ev.window;
  171.     else
  172.     {
  173.       jwindow *last=first;
  174.       for (;last->next;last=last->next);
  175.       last->next=ev.window;
  176.     }
  177.     ev.window->next=NULL;
  178.     if (red)
  179.     {
  180.       jwindow *j=ev.window,*p;
  181. /*      screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  182.       for (p=first;p!=j;p=p->next)
  183.         p->screen->add_dirty(j->x-p->x,j->y-p->y,j->x+j->l-1-p->x,j->y+j->h-1-p->y);*/
  184.       j->screen->add_dirty(0,0,j->l-1,j->h-1);
  185.       flush_screen();
  186.     }
  187.  
  188.         state=dragging;
  189.         drag_window=ev.window;
  190.         drag_mousex=ev.window->x-ev.mouse_move.x;
  191.         drag_mousey=ev.window->y-ev.mouse_move.y;
  192.         ev.type=EV_SPURIOUS;
  193.       } else if (ev.window)
  194.         ev.window->inm->handle_event(ev,ev.window,this);
  195.     }
  196.   } else if (state==dragging)
  197.   {
  198.     ev.window=drag_window;
  199.     if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button==0)  // user released the mouse
  200.     {
  201.       state=inputing;
  202.       ev.type=EV_SPURIOUS;
  203.     } else if (ev.type==EV_MOUSE_MOVE)
  204.     {
  205.        move_window(drag_window,ev.mouse_move.x+drag_mousex,ev.mouse_move.y+drag_mousey);
  206.        flush_screen();
  207.        ev.type=EV_DRAG_WINDOW;
  208.        ev.window_position.x=ev.mouse_move.x+drag_mousex;
  209.        ev.window_position.y=ev.mouse_move.y+drag_mousey;
  210.     }
  211.   } 
  212.   if (ev.type==EV_REDRAW)
  213.   {
  214.     for (j=first;j;j=j->next) 
  215.        j->screen->add_dirty(ev.redraw.x1-j->x,ev.redraw.y1-j->y,
  216.              ev.redraw.x2-j->x,ev.redraw.y2-j->y);
  217.     screen->add_dirty(ev.redraw.x1,ev.redraw.y1,ev.redraw.x2,ev.redraw.y2);
  218.     flush_screen();
  219.     ev.type=EV_SPURIOUS;   // we took care of this one by ourselves.
  220.   }
  221. }
  222.  
  223. void jwindow::resize(int L, int H)
  224. {
  225.   screen->change_size(L,H);
  226.   l=L; h=H;
  227. }
  228.  
  229. void window_manager::resize_window(jwindow *j, int l, int h)
  230. {
  231.   jwindow *p;
  232.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  233.   for (p=first;p!=j;p=p->next)
  234.     p->screen->add_dirty(j->x-p->x,j->y-p->y,j->x+j->l-1-p->x,j->y+j->h-1-p->y);
  235.   j->resize(l,h);
  236.   if (!frame_suppress)
  237.   j->redraw(hi,med,low,frame_font());
  238. }
  239.  
  240. void window_manager::move_window(jwindow *j, int x, int y)
  241. {
  242.   jwindow *p;
  243.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  244.   for (p=first;p!=j;p=p->next)
  245.     p->screen->add_dirty(j->x-p->x,j->y-p->y,j->x+j->l-1-p->x,j->y+j->h-1-p->y);
  246.   j->x=x;
  247.   j->y=y;
  248.   j->screen->add_dirty(0,0,j->l-1,j->h-1);
  249. }
  250.  
  251. window_manager::window_manager(image *Screen, palette *Pal, int Hi, 
  252.                                int Med, int Low, JCFont *Font)
  253. {
  254.   hi=Hi; low=Low; med=Med; first=NULL; pal=Pal; grab=NULL;
  255.   bk=pal->find_closest(0,0,0);
  256.   state=inputing; fnt=Font;  wframe_fnt=Font;
  257.   memset(key_state,0,sizeof(key_state));
  258.   eh=new event_handler(screen,pal);
  259.   frame_suppress=0;
  260. }
  261.  
  262. jwindow *window_manager::new_window(int x, int y, int l, int h, ifield *fields, char *Name)
  263. {
  264.   if (x>screen->width()-4) x=screen->width()-25;
  265.   if (y>screen->height()-4) y=screen->height()-10;
  266.   
  267.   jwindow *j=new jwindow(x,y,l,h,this,fields,Name),*k;
  268.   j->property.hidden=0;
  269.   if (!first)
  270.     first=j;
  271.   else
  272.   {
  273.     k=first;
  274.     while (k->next) k=k->next;
  275.     k->next=j;
  276.     j->next=NULL;
  277.   }
  278.   if (!frame_suppress)
  279.     j->redraw(hi,med,low,frame_font());
  280.   return j;
  281. }
  282.  
  283. void window_manager::flush_screen()
  284. {
  285.   jwindow *p,*q;
  286.  
  287.   int mx,my,but;
  288.   image *mouse_pic,*mouse_save;
  289.   
  290.   if (has_mouse())
  291.   {    
  292.     mouse_pic=eh->mouse_sprite()->visual;
  293.     mouse_save=eh->mouse_sprite()->save;
  294.     mx=eh->mouse->drawx();
  295.     my=eh->mouse->drawy();
  296.  
  297.     screen->add_dirty(mx-1, my-1, mx + mouse_pic->width(), my + mouse_pic->height());
  298.     screen->put_part(mouse_save,0,0,mx,my,mx+mouse_pic->width()-1,my+mouse_pic->height()-1);
  299.     mouse_pic->put_image(screen,mx,my,1);
  300.   }
  301.   
  302.   for (p=first;p;p=p->next)
  303.     if (!p->property.hidden)
  304.        screen->delete_dirty(p->x,p->y,p->x+p->l-1,p->y+p->h-1);
  305.   update_dirty(screen);
  306.  
  307.   if (has_mouse())
  308.     mouse_save->put_image(screen,mx,my);
  309.  
  310.  
  311.   for (p=first;p;p=p->next)
  312.   {
  313.     if (!p->property.hidden)
  314.     {
  315.       if (has_mouse())
  316.       {      
  317.     p->screen->put_part(mouse_save,0,0,mx-p->x,my-p->y,
  318.                 mx-p->x+mouse_pic->width()-1,
  319.                 my-p->y+mouse_pic->height()-1);
  320.     if (has_mouse())
  321.         mouse_pic->put_image(p->screen,mx-p->x,my-p->y,1);
  322.       }
  323.       
  324.  
  325. //      screen->delete_dirty(p->x,p->y,p->x+p->l-1,p->y+p->h-1);
  326.       for (q=p->next;q;q=q->next)
  327.         if (!q->property.hidden)
  328.           p->screen->delete_dirty(q->x-p->x,
  329.                               q->y-p->y,
  330.                               q->x+q->l-1-p->x,
  331.                               q->y+q->h-1-p->y);
  332.       update_dirty(p->screen,p->x,p->y);
  333.       if (has_mouse())
  334.          mouse_save->put_image(p->screen,mx-p->x,my-p->y,0);
  335.     }
  336.   }
  337. }
  338.  
  339. void jwindow::set_moveability(int x)
  340. {
  341.   property.moveable=x;
  342. }
  343.  
  344. jwindow::jwindow(int X, int Y, int L, int H, window_manager *wm, ifield *fields, char *Name)
  345. {
  346.   ifield *i;
  347.   int x1,y1,x2,y2;
  348.   l=0; h=0; 
  349.   property.moveable=1;
  350.   if (fields)
  351.     for (i=fields;i;i=i->next)
  352.     {
  353.       i->area(x1,y1,x2,y2,wm);
  354.       if ((int)y2>(int)h) 
  355.         h=y2+1;
  356.       if ((int)x2>(int)l) 
  357.         l=x2+1;
  358.     }
  359.   else { l=2; h=2; }
  360.  
  361.   if (L<=0) { l=l-L; } else l=L+jw_left;
  362.   if (H<=0) { h=h-H; } else h=H+jw_top;
  363.  
  364.  if (Y<0) y=yres-h+Y-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM-1; else y=Y;
  365.  if (X<0) x=xres-l+X-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT-1; else x=X;
  366.  
  367.   backg=wm->medium_color();
  368.   l+=WINDOW_FRAME_RIGHT; h+=WINDOW_FRAME_BOTTOM;
  369. //  if (!fields) { l+=WINDOW_FRAME_LEFT; h+=WINDOW_FRAME_TOP; }
  370.  
  371.   if (l<18) l=18;
  372.   if (h<12) h=12;
  373.   screen=new image(l,h,NULL,2);
  374.   l=screen->width();
  375.   h=screen->height();
  376.   screen->clear(backg);
  377.   next=NULL;
  378.   inm=new input_manager(screen,wm,fields);
  379.   if (Name==NULL)
  380.     name=strcpy((char *)jmalloc(strlen(" ")+1,"jwindow::window name")," ");  
  381.   else
  382.     name=strcpy((char *)jmalloc(strlen(Name)+1,"jwindow::window name"),Name);
  383. }
  384.  
  385. void jwindow::local_close() { ; }
  386.  
  387. void jwindow::redraw(int hi, int med, int low, JCFont *fnt)
  388. {
  389.   if (jw_right>=3)
  390.     screen->rectangle(0,0,l-3,h-3,low);
  391.   if (jw_right>=2)
  392.     screen->rectangle(1,1,l-2,h-2,med);
  393.   if (jw_right>=1)
  394.     screen->rectangle(2,2,l-1,h-1,hi);
  395.  
  396.  
  397.   
  398.   screen->wiget_bar(0,0,l-1,8,hi,med,low);
  399.   screen->line(1,1,l-2,1,low);
  400.   screen->line(1,3,l-2,3,low);
  401.   screen->line(1,5,l-2,5,low);
  402.   screen->line(1,7,l-2,7,low);
  403.  
  404.   screen->wiget_bar(4,3,10,5,hi,med,low);
  405.   screen->rectangle(3,2,11,6,0);  
  406.  
  407.   screen->line(0,8,l-1,8,0);
  408.   if (jw_right>=1)
  409.     screen->wiget_bar(0,9,l-1,h-1,hi,med,low);  
  410.     screen->wiget_bar(0,9,l-1,h-1,hi,med,low);
  411.   if (jw_right>=2)
  412.     screen->wiget_bar(4,13,l-jw_right,h-jw_right,low,med,hi);
  413.  
  414.  
  415.   if (name && name[0] && (name[0]!=' ' || name[1]))
  416.   {
  417.     short cx1,cy1,cx2,cy2;
  418.     screen->get_clip(cx1,cy1,cx2,cy2);
  419.     screen->set_clip(14,1,l-2,WINDOW_FRAME_TOP-4);
  420.     screen->bar(14,1,14+fnt->width()*strlen(name),15-8,med);
  421.     fnt->put_string(screen,14,1,name,low);  
  422.     screen->set_clip(cx1,cy1,cx2,cy2);
  423.   }
  424.   
  425.   screen->bar(x1(),y1(),x2(),y2(),backg);
  426.   inm->redraw();
  427. }
  428.  
  429.  
  430. ifield *input_manager::unlink(int id)     // unlinks ID from fields list and return the pointer to it
  431.   for (ifield *i=first,*last;i;i=i->next)
  432.   {
  433.     if (i->id==id) 
  434.     {
  435.       if (i==first)
  436.     first=first->next;
  437.       else
  438.         last->next=i->next;
  439.       if (active==i)
  440.         active=first;
  441.       return i;
  442.     }
  443.     ifield *x=i->unlink(id);
  444.     if (x) return x;
  445.     last=i;
  446.   }
  447.   return NULL;   // no such id
  448. }
  449.  
  450. input_manager::~input_manager() 
  451. { ifield *i; 
  452.   while (first) 
  453.   { i=first; 
  454.     first=first->next; 
  455.     delete i; 
  456.   } 
  457.  
  458. void input_manager::clear_current()
  459. {
  460.   if (active)
  461.     active->draw(0,screen,wm);
  462.  
  463.   active=NULL;
  464. }
  465.  
  466.  
  467. void input_manager::next_active(image *screen, window_manager *wm)
  468. {
  469.   active->draw(0,screen,wm);
  470.   do
  471.   {
  472.     active=active->next;
  473.     if (!active) active=first;
  474.   } while (active && !active->selectable());
  475.   active->draw(1,screen,wm);
  476. }
  477.  
  478. void input_manager::handle_event(event &ev, jwindow *j, window_manager *wm)
  479. {
  480.   ifield *i,*in_area=NULL;
  481.   int x1,y1,x2,y2;
  482.   if (j)
  483.   {
  484.     ev.mouse_move.x-=j->x;
  485.     ev.mouse_move.y-=j->y;
  486.     cur=j;
  487.   }
  488.  
  489.   if (!grab)
  490.   {
  491.     if ((ev.type==EV_MOUSE_BUTTON && ev.mouse_button==1) || ev.type==EV_MOUSE_MOVE)
  492.     {
  493.       for (i=first;i;i=i->next)
  494.       {
  495.     i->area(x1,y1,x2,y2,wm);
  496.     if (ev.mouse_move.x>=x1 && ev.mouse_move.y>=y1 &&
  497.         ev.mouse_move.x<=x2 && ev.mouse_move.y<=y2)
  498.         in_area=i;
  499.       }
  500.       if (in_area!=active && (no_selections_allowed || (in_area && in_area->selectable())))
  501.       {
  502.     if (active)
  503.           active->draw(0,screen,wm);
  504.  
  505.     active=in_area; 
  506.  
  507.     if (active)
  508.       active->draw(1,screen,wm);
  509.       }
  510.     } 
  511.     if (ev.type==EV_KEY && ev.key==JK_TAB && active)
  512.     { 
  513.       active->draw(0,screen,wm);
  514.       do
  515.       {
  516.     active=active->next;
  517.     if (!active) active=first;
  518.       } while (active && !active->selectable());
  519.       active->draw(1,screen,wm);
  520.     }
  521.   } else active=grab;
  522.  
  523.   if (active)
  524.   {
  525.     if (ev.type!=EV_MOUSE_MOVE && ev.type!=EV_MOUSE_BUTTON)
  526.       active->handle_event(ev,screen,wm,this);
  527.     else
  528.     {
  529.       active->area(x1,y1,x2,y2,wm);
  530.       if (grab || (ev.mouse_move.x>=x1 && ev.mouse_move.y>=y1 &&
  531.           ev.mouse_move.x<=x2 && ev.mouse_move.y<=y2))
  532.       {
  533.     if (j)
  534.       active->handle_event(ev,screen,wm,j->inm);
  535.     else active->handle_event(ev,screen,wm,this);
  536.       }
  537.     }
  538.   }
  539.  
  540.   if (j)
  541.   {
  542.     ev.mouse_move.x+=j->x;
  543.     ev.mouse_move.y+=j->y;
  544.   }
  545. }
  546.  
  547. void input_manager::allow_no_selections()
  548. {
  549.   no_selections_allowed=1;
  550. }
  551.  
  552. void input_manager::redraw()
  553. {
  554.   ifield *i;
  555.   for (i=first;i;i=i->next)
  556.     i->draw_first(screen,wm);
  557.   if (active)
  558.     active->draw(1,screen,wm);
  559. }
  560.  
  561. input_manager::input_manager(image *Screen, window_manager *WM, ifield *First)
  562. {
  563.   screen=Screen;
  564.   no_selections_allowed=0;
  565.   cur=NULL;
  566.   grab=NULL;
  567.   wm=WM;
  568.   active=first=First;
  569.   while (active && !active->selectable()) active=active->next;
  570.   redraw();
  571. }
  572.  
  573. void input_manager::grab_focus(ifield *i)
  574. { grab=i; 
  575.   if (cur)
  576.     wm->grab_focus(cur);
  577. }
  578.  
  579. void input_manager::release_focus()
  580. { grab=NULL; 
  581.   if (cur)
  582.     wm->release_focus();
  583. }
  584.  
  585. void input_manager::remap(filter *f)
  586. {
  587.   for (ifield *i=first;i;i=i->next)
  588.    i->remap(f);
  589.   redraw();
  590. }
  591.  
  592. void input_manager::add(ifield *i) 
  593. { ifield *f=first;
  594.   if (i->selectable())
  595.   {
  596.     if (!f)
  597.       first=i;
  598.     else
  599.     {
  600.       while (f->next) f=f->next;
  601.       f->next=i; 
  602.     }
  603.   }
  604. }
  605.  
  606. ifield *input_manager::get(int id)
  607. {
  608.   ifield *f;
  609.   for (f=first;f;f=f->next)
  610.   {
  611.     ifield *ret=f->find(id);
  612.     if (ret) return ret;
  613.   }
  614.   return NULL;
  615. }
  616.  
  617.  
  618.  
  619.